﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-08-02
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


class IFSpriteObject;
class IFSpriteGroup;
class IFSpriteFile;
class IFSprite;


//----------------------------------------------------------------
// 单个精灵对象
//----------------------------------------------------------------
class IFSpriteObject : public IFMemObject
{
public:
    // 获取中心位置
    virtual void GetCenter(float& cx, float& cy) = 0;
    // 调整中心位置
    virtual void SetCenter(float cx, float cy) = 0;
    // 获取混合模式
    virtual DWORD GetRenderFlags() = 0;
    // 调整混合模式
    virtual void SetRenderFlags(DWORD flags) = 0;
    // 获取翻转状态，详见 EF_REVERSAL_MODE
    virtual BYTE GetReversalMode() = 0;
    // 设置是否反转，详见 EF_REVERSAL_MODE
    virtual void SetReversalMode(BYTE mode) = 0;
    // 获取颜色混合值，ARGB格式
    virtual DWORD GetColor() = 0;
    // 设置颜色混合值，ARGB格式
    virtual void SetColor(DWORD color) = 0;
    // 获取源图区域
    virtual void GetSpriteRect(float& sx, float& sy, float& sw, float& sh) = 0;
    // 设置源图区域
    virtual void SetSpriteRect(float sx, float sy, float sw, float sh) = 0;
    // 获取精灵宽度
    virtual float GetWidth() = 0;
    // 获取精灵高度
    virtual float GetHeight() = 0;
    // 获取精灵使用的贴图ID
    virtual FIDTEXTURE GetTextureID() = 0;
    // 获取精灵的分组ID
    virtual int GetGroupID() = 0;
    // 渲染到指定位置
    virtual void Render(float x, float y) = 0;
    // 渲染到指定位置，并附带旋转、缩放
    virtual void RenderEx(float x, float y, float rot, float hscale=1.0f, float vscale=0.0f) = 0;
    // 渲染到屏幕指定左上和右下位置
    virtual void RenderStretch(FVECTOR2* p0, FVECTOR2* p1) = 0;
    // 渲染到指定四个位置，点的顺序按Quad说明排列,见IFRender.h文件顶部
    virtual void Render4V(FVECTOR2* p0, FVECTOR2* p1, FVECTOR2* p2, FVECTOR2* p3) = 0;
    // 平铺模式渲染到目录位置
    virtual void RenderTiled(FRect* dst) = 0;
    // 复杂碎片渲染模式（EF_SPRITE_TILE_DRAW_MODE）
    virtual void RenderTileEx(EF_SPRITE_TILE_DRAW_MODE md, FRect* dst, FRect* nine_rc) = 0;
    virtual void RenderTileEx(EF_SPRITE_TILE_DRAW_MODE md, float dx, float dy, float dw, float dh, float nx, float ny, float nw, float nh) = 0;
};


//----------------------------------------------------------------
// 精灵组
//----------------------------------------------------------------
class IFSpriteGroup : public IFMemObject
{
public:
    // 取本组精灵数量
    virtual size_t GetCount() = 0;
    // 取得本组指定精灵
    virtual IFSpriteObject* Get(size_t spr_idx) = 0;
    // 开始播放
    virtual void Start() = 0;
    // 设置单步间隔，step要求至少为5
    virtual void SetStep(int step) = 0;
    // 取得单步间隔
    virtual int GetStep() = 0;
    // 设置动画模式
    virtual void SetMode(EF_ANIMATE_MODE mode) = 0;
    // 取得动画模式
    virtual EF_ANIMATE_MODE GetMode() = 0;
    // 渲染到指定位置
    virtual void Render(float x, float y) = 0;
    // 渲染到指定位置，并附带旋转、缩放
    virtual void RenderEx(float x, float y, float rot, float hscale=1.0f, float vscale=0.0f) = 0;
};


//----------------------------------------------------------------
// 精灵数据
//----------------------------------------------------------------
class IFSpriteFile : public IFFileObject
{
public:
    // 获取此精灵文件所在引擎
    virtual IFEngine* GetEngine() = 0;
    // 取得此精灵动画的ID
    virtual FIDSPRITE GetSpriteID() = 0;
    // 取得贴图ID
    virtual FIDTEXTURE GetTextureID() = 0;
    // 取得精灵对象数量
    virtual size_t GetCount() = 0;
    // 通过索引取得精灵对象
    virtual IFSpriteObject* Get(size_t index) = 0;
    // 通过HASH取得精灵对象
    virtual IFSpriteObject* Get(FIDHASH hash) = 0;
    // 通过名字取得精灵对象
    FINLINE IFSpriteObject* Get(const WCHAR* name);
    FINLINE IFSpriteObject* Get(const ACHAR* name);
    // 通过分组ID取得分组数据
    virtual IFSpriteGroup* GetGroup(int group_id) = 0;
    // 通过分组索引取分组数据
    virtual IFSpriteGroup* GetGroupByIndex(size_t idx) = 0;
    // 获取分数数量（0号分组默认必须存在的）
    virtual size_t GetGroupCount() = 0;
};


//----------------------------------------------------------------
// 精灵管理器
//----------------------------------------------------------------
class IFSprite : public IFService
{
protected:
    explicit IFSprite()
        :IFService(0)
    {}

public:
    // 加载精灵动画
    // .return 成功返回有效ID，失败返回eCD_ErrorSprite
    virtual FIDSPRITE Create(const WCHAR* filename) = 0;
    virtual FIDSPRITE Create(const ACHAR* filename) = 0;
    // 通过文件缓存创建（注意，由于不是通过文件创建的，因此没有加载计数功能，需要手动控制，以防重复加载到内存）
    virtual FIDSPRITE Create(const BYTE* fsd_buf, size_t fsd_size, const BYTE* png_buf, size_t png_size) = 0;
    // 释放精灵动画
    virtual void Destroy(FIDSPRITE id) = 0;
    // 释放精灵动画，并自动将id设置为eCD_ErrorSprite
    virtual void DestroyEx(FIDSPRITE& id) = 0;
    // 通ID取得精灵动画文件
    virtual IFSpriteFile* Get(FIDSPRITE id) = 0;
    // 取得指定精灵文件使用的贴图ID
    virtual FIDTEXTURE GetTextureID(FIDSPRITE id) = 0;
    // 取得精灵对象数量
    virtual size_t GetCount(FIDSPRITE id) = 0;
    // 通过精灵文件ID取得指定精灵对象
    virtual IFSpriteObject* Get(FIDSPRITE id, size_t spr_idx) = 0;
    // 通过精灵文件ID取得指定精灵对象
    virtual IFSpriteObject* Get(FIDSPRITE id, FIDHASH hash) = 0;
    // 通过精灵文件ID取得指定精灵对象
    virtual IFSpriteObject* Get(FIDSPRITE id, const WCHAR* spr_name) = 0;
    virtual IFSpriteObject* Get(FIDSPRITE id, const ACHAR* spr_name) = 0;
    // 通过精灵文件ID取得指定精灵分组
    virtual IFSpriteGroup* GetGroup(FIDSPRITE id, int group_id) = 0;
};